package com.hup.utils.commons.exception.parser;

import com.hup.utils.commons.exception.ErrParserRegister;
import com.hup.utils.commons.exception.ExceptionMsgParser;
import com.hup.utils.commons.exception.TraceHandler;
import org.apache.ibatis.exceptions.PersistenceException;
import org.mybatis.spring.MyBatisSystemException;
import org.springframework.jdbc.CannotGetJdbcConnectionException;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * 注册时,需要有以下依赖
 * <pre>
 * <dependency>
 * <groupId>org.mybatis.spring.boot</groupId>
 * <artifactId>mybatis-spring-boot-starter</artifactId>
 * <version>2.0.1</version>
 * </dependency>
 * </pre>
 *
 * @author hugan
 * @date 2019/12/12
 * @apiNote 未完成
 */
public class MyBatisMsgParser implements ErrParserRegister {

    @Override
    public List<ExceptionMsgParser> getParsers() {
        ArrayList<ExceptionMsgParser> list = new ArrayList<>();
        list.add(new MyBatisSystem());
        return list;
    }

    private static class MyBatisSystem implements ExceptionMsgParser<MyBatisSystemException> {
        @Override
        public String getMsg(MyBatisSystemException e) {
            Throwable cause;
            if ((cause = e.getCause()) instanceof PersistenceException
                    && cause.getCause() instanceof CannotGetJdbcConnectionException) {
                return "数据库连接失败,请检查相关配置和服务";
            }
            return e.getMessage();
        }

        @Override
        public String getTrace(MyBatisSystemException e) {
            Throwable cause;
            if ((cause = e.getCause()) instanceof PersistenceException
                    && (cause = cause.getCause()) instanceof CannotGetJdbcConnectionException
                    && (cause = cause.getCause()) instanceof SQLException) {
                //发生这种异常后,框架会自动打印一堆堆栈信息,目前不做拦截
                //把 Access denied for user 'user'@'localhost'打印到堆栈信息(不是在异常信息中显示给前台)
                return "\n" + cause.toString() + TraceHandler.TRACE_HANDLER.getTrace(e);
            }
            return TraceHandler.TRACE_HANDLER.getTrace(e);
        }
    }

}
